import { getDvaApp } from 'umi';
import _, { get as _get } from 'lodash';
import { Modal, notification } from 'antd';
import { getOrganizationInfo } from './organization';
import { getUserInfo } from './user';

// 记录恢复的URI地址
export const URI_NAME = 'sourceUri';

export const globalRef = {
  current: {},
};

export function setGlobalRef(object: any) {
  // const { dispatch } = getDvaApp()._store;
  if (object.ref) {
    // dispatch({
    //   type: "global/setGlobalRef",
    //   payload: object,
    // });
    const { key, ...res } = object as any;
    globalRef.current[key] = res;
  }
}

/**
 * 获取model中的某个属性
 * @param path path可以是modal的namespace，或者state中某个具体的属性
 * 例如path='config'获取到namespace为config的状态
 *     path = 'config.SYSMGMT_CONFIG.workflow'则可以获取到workflow的值
 */
export const getModelData = (path: string) => {
  const dvaApp = getDvaApp();
  if (!dvaApp) {
    console.warn('dvaApp还未初始化<--->注意可能在获取值有问题');
    return null;
  }
  const store = dvaApp._store.getState();
  if (typeof store !== 'object') {
    throw new Error(`redux初始异常`);
  }
  return _get(store, path);
};

/**
 *
 *根具pathname 判断viewKey
 * @param {string} path
 * @returns
 */
export const getViewKey = (path: string) => {
  if (!path || path.indexOf('/') < 0) {
    return path;
  }
  const pathTemp = path.split('?')[0];
  const pathArr = pathTemp.split('/');
  let viewKey = pathArr[pathArr.length - 1];
  pathArr.forEach((item: string, index: number) => {
    if (item.includes('detail')) {
      viewKey = pathArr[index - 1];
    }
  });
  return viewKey;
};

// 将css变量格式装换成小驼峰
//  `--primary-color:blue;--sider-menu-bg:red` => `{primaryColor:'blue',siderMenuBg:'red'}`
export function cssVar2camel(styles: string, keys2format: string[]) {
  function formatCamel(str: string) {
    return str
      .slice(2)
      .split('-')
      .map((V, I) => (I ? V[0].toUpperCase() : V[0]) + V.slice(1))
      .join('');
  }
  return Object.entries(styles)
    .filter(([key]) => key.startsWith('--') && keys2format.includes(formatCamel(key)))
    .reduce((prev, curt) => {
      const [key, value] = curt;
      const camelKey = formatCamel(key);
      return {
        ...prev,
        [camelKey]: value,
      };
    }, {});
}

// 将小驼峰转换成css变量格式
//  `{primaryColor:'blue',siderMenuBg:'red'}` => `--primary-color:blue;--sider-menu-bg:red`
export function camel2cssVar(config: object, keys2format: string[]) {
  return Object.entries(config)
    .filter(([key]) => keys2format.includes(key))
    .reduce((prev, curt) => {
      const [key, value] = curt;
      const cssVar = `--${key.replace(/([A-Z])/g, '-$1').toLowerCase()}`;
      return {
        ...prev,
        [cssVar]: value,
      };
    }, {});
}

// 格式化配置里面的图标
export const updateFavicon = (img: string) => {
  const link = document.createElement('link');
  link.type = 'image/x-icon';
  link.rel = 'shortcut icon';
  link.href = img;
  document.getElementsByTagName('head')[0].appendChild(link);
};

// 修改配置中的路径图片
export const transferImageUrl = (config: object) => {
  // 格式化配置里面图片路径，..表示搜索src下面的所有目录
  // require.context 是 Webpack 提供的一个用于动态导入模块的 API
  // 参数1：搜素的目录  参数2：是否搜索子目录  参数3：匹配文件的正则表达式， 参数4: 加载模式（sync/async），默认同步
  const context = require.context('../assets', true, /\.(png|jgp|jpeg)$/);
  const images = context.keys() as string[];
  for (const _key in config) {
    if (config.hasOwnProperty(_key)) {
      const configItem = config[_key];
      const imagePath = images.find((path) => path.includes(configItem));
      if (imagePath) {
        // context根据key获取组件模块
        config[_key] = context(imagePath);
      }
    }
  }
};

//判断是否包含这个功能点
export function auth(optionKey: string) {
  if (getModelData('user.isSuperAdmin')) return true;
  const permissionData = getModelData('user.permission');
  return permissionData.indexOf(optionKey) >= 0;
}

/**
 * 获取当前用户对象
 * @returns
 */
export function getCurrentUser() {
  return getModelData('user.currentUser') || {};
}

// 获取图片地址
export function getImageById(pictureId: string | number): string {
  return `${window.routerBase}fwSecurity/accountUser/getUserPicture.api?pictureId=${pictureId}`;
}

/**
 *平行数据转树
 *
 * @export
 * @param {any[]} data //平行数据
 * @param {string} [parentKey='parentId'] //父级key
 * @param {string} [childrenKey='children'] //生成的子集key
 * @param {string} [indexKey='index']   //排序字段
 * @param {boolean} [idToString=false]   //是否把id专为字符
 * @param {string} [idKey='id']   //id key
 * @returns {any[]}
 */
export function generateTree(
  data: any[],
  parentKey: string = 'parentId',
  childrenKey: string = 'children',
  indexKey: string = 'index',
  idToString: boolean = false,
  idKey: string = 'id',
): any[] {
  const dataT = _.cloneDeep(data);
  //for循环法
  dataT.forEach(function (item) {
    delete item[childrenKey];
  });
  const levelsMap = {};
  const map = {};
  dataT.forEach(function (item) {
    map[item[idKey]] = item;
  });
  const val: any[] = [];
  dataT.forEach(function (item) {
    const parent = map[item[parentKey]];
    if (parent) {
      (parent[childrenKey] || (parent[childrenKey] = [])).push(item);
    } else {
      val.push(item);
    }
    if (levelsMap[item[parentKey]] == undefined) {
      item.nodeLevel = levelsMap[item[idKey]] = 0;
    } else {
      item.nodeLevel = levelsMap[item[idKey]] = levelsMap[item[parentKey]] + 1;
    }
  });

  let numberTemp = 0;
  function generateNumber(value: any[]) {
    value.map((item: any) => {
      ++numberTemp;
      item[indexKey] = numberTemp;
      if (idToString) {
        item.id = item.id + '';
      }
      if (item[childrenKey]) {
        generateNumber(item[childrenKey]);
      }
    });
  }
  generateNumber(val);
  return val;
}

// 上下margin高度
export const MARGIN_HEIGHT = 5;
// 面包屑高度
export const BREAD_CRUMB_HEIGHT = 24;

/**
 * 适用于获取内容区域(除header,面包屑以外)的diff高度
 * @param MAIN_CONFIG
 * @param diff
 */
export const getContentDiff = (MAIN_CONFIG: MainConfigIF, diff?: number) => {
  const { headerHeight, showBreadcrumb, fullscreen } = MAIN_CONFIG;
  const ContentPaddingTop = headerHeight + (showBreadcrumb ? 0 : MARGIN_HEIGHT);
  const BreadcrumbHeight = showBreadcrumb ? BREAD_CRUMB_HEIGHT : 0;
  const tempDiff = typeof diff === 'undefined' ? 0 : diff;
  const marginBottom = MARGIN_HEIGHT;
  const FinalDiffHeight = (fullscreen ? 0 : BreadcrumbHeight + ContentPaddingTop + marginBottom) + tempDiff;
  return FinalDiffHeight + 1;
};

/**
 * 适用于获取内容区域(除header,面包屑以外)的高度
 * @param MAIN_CONFIG
 * @param diff
 */
export const getContentHeight = (MAIN_CONFIG: MainConfigIF, diff?: number) => {
  const FinalDiffHeight = getContentDiff(MAIN_CONFIG, diff);
  return `calc(100vh - ${FinalDiffHeight}px)`;
};

//通用文案
type commonTextProps = {
  noData: string;
  noSelections: string;
  noSelectionSingle: string;
  noActionText: string;
  doSearchOnChangedText: string;
  doCancelOnChangedText: string;
  doRefreshOnChangedText: string;
  gridEditPromptText: string;
  removeConfirmText: string;
  smartSearchTitleText: string;
  smartGridTitleText: string;
  terminationTip: string;
};
export const commonText: commonTextProps = {
  noData: '暂无数据',
  noSelections: '还未选择数据',
  noSelectionSingle: '还未选择单条数据',
  noActionText: '无任何操作',
  doSearchOnChangedText: '表格内容已发生变化,是否放弃修改并查询',
  doCancelOnChangedText: `表格内容已发生变化,是否放弃修改?`,
  doRefreshOnChangedText: `表格内容已发生变化,是否刷新?`,
  gridEditPromptText: `表格内容已发生变化,是否放弃修改并离开?`,
  removeConfirmText: `确定删除?`,
  smartSearchTitleText: '查询',
  smartGridTitleText: '列表',
  terminationTip: '是否确认执行终止操作?已发起流程需先撤销,是否确认?',
};

/*
生成uuid
len:number  长度
radix:number  进制
*/
export function generateUuid(len: number = 32, radix: number = 10): string {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
  const uuid = [];
  let i;
  const radixT = radix || chars.length;
  if (len) {
    for (i = 0; i < len; i++) {
      uuid[i] = chars[0 | (Math.random() * radixT)];
    }
  } else {
    let r;
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
    uuid[14] = '4';
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16);
        uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
      }
    }
  }
  return uuid.join('');
}

// 动态header，存储登录验证相关信息
export const dynamicHeader = {
  current: {},
};

//获取用户身份
export function getUserIdentity(): any {
  return dynamicHeader.current;
}

/**
 * JSON深拷贝
 */
export const deepCopy4JSON: <T>(data: T) => T = (obj) => JSON.parse(JSON.stringify(obj));

// Modal header 高度
export const MODAL_HEADER_HEIGHT = 31;

// Modal 上下单个 padding 高度
export const MODAL_PADDING_HEIGHT = 10;

// Modal footer 高度
export const MODAL_FOOTER_HEIGHT = 31;

// 消息提示
export const confirmUtil = (props: {
  okType?: 'link' | 'default' | 'dashed' | 'primary' | 'ghost' | 'danger';
  content: string | ReactNode; //提示内容
  solveBySelf?: boolean; //回调自行resolve or reject
  onOk: () => void; //确定按钮触发方法
  [key: string]: any;
}) => {
  const { content, onOk, solveBySelf = false, okType = 'danger', ...restProps } = props;
  Modal.confirm({
    title: '提示',
    content,
    cancelText: '取消',
    okText: '确定',
    okType,
    okButtonProps: {
      size: 'small',
    },
    cancelButtonProps: {
      size: 'small',
    },
    onOk() {
      return new Promise((resolve, reject) => {
        if (solveBySelf) {
          onOk && onOk(resolve, reject);
        } else {
          onOk && onOk();
          resolve(true);
        }
      });
    },
    onCancel() {},
    ...restProps,
  });
};

/**
 * 根据错误信息渲染内容
 * @param valids
 * @returns
 */
export function renderValids(valids: any): React.ReactNode {
  const mapError = (valid: any, i: number, index: any) => {
    let span = <span style={{ fontWeight: 'bold', color: 'var(--error-color)' }}> {valid.message}, </span>;
    if (i === valids[index].length - 1) {
      span = (
        <span
          style={{
            fontWeight: 'bold',
            color: 'var(--error-color)',
          }}
        >
          {' '}
          {valid.message}
        </span>
      );
    }
    return span;
  };

  return Object.keys(valids).map((index, _i) => (
    <div key={_i}>
      {isNaN(Number(index)) ? (
        <>
          由于过滤导致的隐藏行
          {_.uniqBy(valids[index], 'field').map((valid: any, i: number) => mapError(valid, i, index))}
        </>
      ) : (
        <>
          第{Number(index) + 1}行{valids[index].map((valid: any, i: number) => mapError(valid, i, index))}
        </>
      )}
    </div>
  ));
}

/**
 *提示数据校验信息
 *
 * @export
 * @param {object} valids
 */
export function showValidate(
  valids: object,
  extraProps: {
    message?: string;
    customContentBeforeValids?: ReactNode;
    customContentAfterValids?: ReactNode;
  } = {},
) {
  const { message = '提示', customContentBeforeValids = null, customContentAfterValids = null } = extraProps;

  if (!_.isEmpty(valids) || customContentBeforeValids || customContentAfterValids) {
    notification.error({
      message,
      description: (
        <div
          style={{
            maxHeight: 'calc(100vh - 90px)',
            overflowY: 'auto',
          }}
        >
          {customContentBeforeValids}
          {valids && renderValids(valids)}
          {customContentAfterValids}
        </div>
      ),
      duration: 5,
    });
  }
}

//通用nofitication 提示 （默认为无任何操作）
export const showActionText = (props?: any) => {
  notification.warning({
    message: '提示',
    description: commonText.noActionText,
    placement: 'bottomRight',
    duration: 2,
    ...props,
  });
};

//全局拦截
export const setPrompt = (toPrompt?: boolean, messsage?: string) => {
  const dispatch = getDvaApp()._store.dispatch;
  if (toPrompt) {
    dispatch({
      type: 'global/save',
      payload: {
        prompt: true,
        promptMessage: commonText.gridEditPromptText || messsage,
      },
    });
  } else {
    dispatch({ type: 'global/save', payload: { prompt: false } });
  }
};

// 根据width换算栅格占位格数
export function spanCalculate(width: number): number {
  if (!width) {
    return 4;
  }
  if (width <= 300) {
    return 24;
  }
  if (width > 300 && width <= 576 + 5) {
    return 12;
  }
  if (width > 576 && width <= 768 + 5) {
    return 8;
  }
  if (width > 768 && width <= 992 + 5) {
    return 6;
  }
  if (width < 992 && width <= 1200 + 5) {
    return 6;
  }
  if (width < 1200 && width < 1600 + 5) {
    return 4;
  }
  if (width >= 1600) {
    return 3;
  }
  return 4;
}

// 获取谷歌浏览器版本
export function getChromeVersion() {
  const arr = navigator.userAgent.split(' ');
  let chromeVersion = '';
  for (let i = 0; i < arr.length; i++) {
    if (/chrome/i.test(arr[i])) chromeVersion = arr[i];
  }
  if (chromeVersion) {
    return Number(chromeVersion.split('/')[1].split('.')[0]);
  } else {
    return false;
  }
}

//不包含业务信息的公共utils
/**
 * 判断ie版本
 */
function IEVersion() {
  const { userAgent } = navigator; // 取得浏览器的userAgent字符串
  const isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1; // 判断是否IE<11浏览器
  const isEdge = userAgent.indexOf('Edge') > -1 && !isIE; // 判断是否IE的Edge浏览器
  const isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;
  if (isIE) {
    const reIE = new RegExp('MSIE (\\d+\\.\\d+);');
    reIE.test(userAgent);
    const fIEVersion = parseFloat(RegExp.$1);
    if (fIEVersion == 7) {
      return 7;
    }
    if (fIEVersion == 8) {
      return 8;
    }
    if (fIEVersion == 9) {
      return 9;
    }
    if (fIEVersion == 10) {
      return 10;
    }
    return 6; // IE版本<=7
  }
  if (isEdge) {
    return 'edge'; // edge
  }
  if (isIE11) {
    return 11; // IE11
  }
  return -1; // 不是ie浏览器
}

/**
 * 判断是否为ie浏览器
 */
export function isIE() {
  const ieVersion = IEVersion();
  return ieVersion !== -1 && ieVersion !== 'edge';
}

//dom向上冒泡获取父节点
const findParentNode = (node: HTMLElement, className: string): HTMLElement => {
  const target: HTMLElement = node;
  if (!target.parentElement) {
    return target;
  }
  if (target.classList.contains(className)) {
    return target;
  }
  return findParentNode(target.parentElement, className);
};

/**
 * 下拉框设置统一挂载点
 *
 * @param {any} triggerNode
 */
export const getGantPopupContainer = (triggerNode: HTMLElement) => {
  return findParentNode(triggerNode, 'gant-layout');
};

//通过链接生成searchParams或者query对象
export const getSearchParams = (href: string, object?: boolean): any => {
  const searchStr = href.split('?')[1];
  const searchParams = new URLSearchParams(searchStr);
  if (object) {
    const obj = {};
    for (const [key, value] of searchParams.entries()) {
      obj[key] = value;
    }
    return obj;
  }
  return searchParams;
};

//删除用户身份
export function deleteUserIdentity(): any {
  // delCookie('userIdentity')
  localStorage.removeItem('userIdentity');
}

//国际化映射字典
export const LOCALE_MAP = {
  'zh-CN': 'zh_CN',
  'en-US': 'en',
};

/**
 * 获取组织列filter配置
 * @param fieldName 当前字段名
 */
export function getOrgColumnFilter(fieldName: string) {
  return {
    filterValueGetter: (params: any) => {
      // 获取对应组织id
      const id = _get(params, 'data.' + fieldName);
      // 根据id获取组织对象
      const org: any = getOrganizationInfo(id) || {};
      return org.fullOrgName;
    },
  };
}

/**
 * 获取用户列filter配置
 * @param fieldName 当前字段名
 */
export function getUserColumnFilter(fieldName: string, isUserId: boolean = true) {
  return {
    filterValueGetter: (params: any) => {
      // 获取对应用户id
      const value = _get(params, 'data.' + fieldName);
      if (!value) return '';
      // 根据id获取用户对象
      let user: any = {};
      if (isUserId) {
        user = getUserInfo(value) || {};
      } else {
        user = getUserInfo('', value) || {};
      }
      if (MAIN_CONFIG && _.get(MAIN_CONFIG, 'userColumnShowLogin', '')) {
        return user.userName ? user.userName + '-' + user.userLoginName : '';
      } else {
        return user.userName;
      }
    },
  };
}

/**
 * 校验当前用户是否是【供应商用户】
 * @returns
 */
export function checkIsSupplier() {
  return (
    getModelData('user.currentUser.userType') != 'EMPLOYEE' &&
    getModelData('user.currentUser.userLoginName') != 'iP2Admin'
  );
  // || true
}

// 初始格式请求接口参数
export const initParams = {
  pageInfo: {
    pageSize: 50,
    beginIndex: 0,
  },
  filterInfo: {
    filterModel: true,
  },
};
